package com.engine
{
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import away3d.controllers.HoverController;
	import away3d.debug.AwayStats;
	import away3d.lights.LightBase;
	import away3d.materials.lightpickers.StaticLightPicker;
	import away3d.textures.PlanarReflectionTexture;

	import com.greensock.TweenLite;

	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class AwayEngine
	{
		private static var reflect:PlanarReflectionTexture;

		public static function addReflect(r:PlanarReflectionTexture):void
		{
			reflect=r;
		}

		public static function get senceHeight():int
		{
			return nativeStage.stageHeight;
		}

		public static function get senceWidth():int
		{
			return nativeStage.stageWidth;
		}

		private static var _view3D:View3D;

		public static function get view3D():View3D
		{
			return _view3D;
		}

		public static function get camera():Camera3D
		{
			return _view3D.camera;
		}

		public static function addMesh(obj:ObjectContainer3D):void
		{
			_view3D.scene.addChild(obj);
		}

		public static function removeMesh(obj:ObjectContainer3D):void
		{
			if (obj.parent != null)
			{
				obj.parent.removeChild(obj);
			}
		}

		private static var _lightPicker:StaticLightPicker;

		public static function get lightPicker():StaticLightPicker
		{
			if (_lightPicker == null)
				createPicker();
			return _lightPicker;
		}

		private static var lightList:Array;

		public static function addLight(light:LightBase):void
		{
			if (_lightPicker == null)
			{
				createPicker();
			}
			lightList.push(light);
			addMesh(light);
			_lightPicker.lights=lightList;
		}

		public static function removeLight(light:LightBase):void
		{
			if (lightList == null)
			{
				return;
			}
			var index:int=lightList.indexOf(light);
			if (index >= 0)
			{
				lightList.splice(index, 1);
				_lightPicker.lights=lightList;
				removeMesh(light);
			}
		}

		private static function createPicker():void
		{
			lightList=[];
			_lightPicker=new StaticLightPicker(lightList);
		}

		private static var cameraController:HoverController; //360全景展示相机控制器
		private static var nativeStage:flash.display.Stage;
//		private static var starlingStage:starling.display.Stage;

		private static var lastPanAngle:Number;
		private static var lastTiltAngle:Number;
		private static var lastMouseX:Number;
		private static var lastMouseY:Number;
		private static var move:Boolean;

		public static function createView(s:flash.display.Stage, /*ss:starling.display.Stage,*/ anti:int=4, canUpdate:Boolean=true):View3D
		{
			nativeStage=s;
//			starlingStage = ss;
			initView(anti);
			cameraEnabled=true;
			if (canUpdate)
			{
				s.addEventListener(Event.ENTER_FRAME, onUpdate);
			}
			nativeStage.scaleMode=StageScaleMode.NO_SCALE;
			nativeStage.align=StageAlign.TOP_LEFT;
			return _view3D;
		}

		private static var _cameraEnabled:Boolean;

		public static function set cameraEnabled(value:Boolean):void
		{
			_cameraEnabled=value;
			if (value)
			{
//				starlingStage.addEventListener(TouchEvent.TOUCH,stageTouch);
				nativeStage.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
				nativeStage.addEventListener(MouseEvent.MOUSE_DOWN, stageTouch);
				nativeStage.addEventListener(MouseEvent.MOUSE_UP, stageTouch);
				nativeStage.addEventListener(Event.MOUSE_LEAVE, stageTouch);
				nativeStage.addEventListener(Event.RESIZE, onResize);
			}
			else
			{
//				starlingStage.removeEventListener(TouchEvent.TOUCH,stageTouch);
				nativeStage.removeEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
				nativeStage.removeEventListener(MouseEvent.MOUSE_DOWN, stageTouch);
				nativeStage.removeEventListener(MouseEvent.MOUSE_UP, stageTouch);
				nativeStage.removeEventListener(Event.MOUSE_LEAVE, stageTouch);
				nativeStage.removeEventListener(Event.RESIZE, onResize);
				onMouseUp();
			}
		}

		public static function stageTouch(e:Event):void
		{
//			var touch:Touch = e.getTouch(starlingStage);
//			if(touch)
//			{
			switch (e.type /*touch.phase*/)
			{
				case MouseEvent.MOUSE_DOWN:
					onMouseDown();
					break;
				case Event.MOUSE_LEAVE:
				case MouseEvent.MOUSE_UP:
					onMouseUp();
					break;
			}
//			}
		}

		public static function addResize(func:Function):void
		{
			nativeStage.addEventListener(Event.RESIZE, func);
		}

		public static function removeResize(func:Function):void
		{
			nativeStage.removeEventListener(Event.RESIZE, func);
		}

		/**
		 * 侦听舞台尺寸改变事件
		 */
		private static function onResize(event:Event=null):void
		{
			_view3D.width=nativeStage.stageWidth;
			_view3D.height=nativeStage.stageHeight;
			_stats.x=_stats.y=0;
		}

		private static var _stats:AwayStats; //调试窗口

		public static function set showStats(value:Boolean):void
		{
			if (value)
			{
				if (_stats == null)
				{
					_stats=new AwayStats(_view3D);
				}
				nativeStage.addChild(_stats);
			}
			else
			{
				if (_stats != null)
				{
					nativeStage.removeChild(_stats);
				}
			}
		}

		/**
		 * 鼠标按下事件
		 */
		private static function onMouseDown():void
		{
			if (cameraController == null || !_cameraEnabled)
			{
				return; //不能交互
			}
//			trace('触发触摸舞台');
			lastPanAngle=cameraController.panAngle;
			lastTiltAngle=cameraController.tiltAngle;
			lastMouseX=nativeStage.mouseX;
			lastMouseY=nativeStage.mouseY;
			move=true;
		}

		/**
		 * 鼠标弹起事件
		 */
		private static function onMouseUp():void
		{
			move=false;
		}

		private static var _perDistance:Number=100; //放大镜移动的距离

		public static function get perDistance():Number
		{
			return _perDistance;
		}

		public static function set perDistance(value:Number):void
		{
			_perDistance=value;
		}

		private static function onWheel(e:MouseEvent):void
		{
			if (e.delta > 0)
			{
				zoomCamera(false);
			}
			else
			{
				zoomCamera(true);
			}
		}

		/**
		 * 让相机临时停止旋转
		 */
		public static function stopCamera():void
		{
			move=false;
		}

		public static function zoomCamera(isLarge:Boolean=false):void
		{
			if (isLarge)
			{
				if (cameraController.distance > minDistance)
				{
					TweenLite.to(cameraController, .5, {distance: cameraController.distance - _perDistance});
				}
			}
			else
			{
				if (cameraController.distance < maxDistance)
				{
					TweenLite.to(cameraController, .5, {distance: cameraController.distance + _perDistance});
				}
			}
		}

		private static function initView(anti:int):void
		{
			if (_view3D == null)
			{
				_view3D=new View3D();
			}
			_view3D.antiAlias=anti;
			_view3D.backgroundColor=0;
			_view3D.backgroundAlpha=0;
		}

		private static function initCamera(camera:Camera3D):void
		{
			if (cameraController == null)
			{
				cameraController=new HoverController(camera);
			}
		}

		private static var minDistance:Number;
		private static var maxDistance:Number;

		public static function setCamera(minDis:Number, maxDis:Number, minTiltAngle:Number=0, maxTiltAngle:Number=90, panAngle:Number=45, tiltAngle:Number=20):void
		{
			minDistance=minDis;
			maxDistance=maxDis;
			initCamera(_view3D.camera);
			cameraController.distance=(maxDis + minDis) / 2; //摄像机和目标点距离
			cameraController.minTiltAngle=minTiltAngle; //摄像机以Y轴旋转最小角度
			cameraController.maxTiltAngle=maxTiltAngle; //摄像机以Y轴旋转最大角度
			cameraController.panAngle=panAngle; //摄像机以Y轴旋转角度
			cameraController.tiltAngle=tiltAngle; //摄像机以X轴旋转角度
		}

		public static function onUpdate(event:Event=null):void
		{
			// 渲染3D世界
			if (move)
			{
				cameraController.panAngle=0.3 * (nativeStage.mouseX - lastMouseX) + lastPanAngle;
				cameraController.tiltAngle=0.3 * (nativeStage.mouseY - lastMouseY) + lastTiltAngle;
			}
			if (reflect != null)
			{
				if (cameraController != null)
				{
					cameraController.update();
				}
				reflect.render(_view3D);
			}
			_view3D.render();
		}

		public static function addLoop(handler:Function):void
		{
			nativeStage.addEventListener(Event.ENTER_FRAME, handler);
		}

		public static function removeLoop(handler:Function):void
		{
			nativeStage.removeEventListener(Event.ENTER_FRAME, handler);
		}

		public static function control(handler:Function):void
		{
			nativeStage.addEventListener(MouseEvent.CLICK, handler);
		}


	}
}
